<?php

namespace org\phpstruct\db\driver;

use org\phpstruct\core;
use org\phpstruct\core\I;

class OCI implements DBDriverInterface {

    private static $instance;
    /**
     * Rebel_Config_Rebel_Config_XMLConfig object
     *
     * @var Rebel_Config_XMLConfig
     */
    private static $xcfg;
    /**
     * PDO Connection handler
     *
     * @var PDO
     */
    private static $dbh;
    public static $DRIVER_NAME = null;

    public function __construct($tns, $username, $password) {
        $tns = str_replace('oci:dbname=', '', $tns);
        self::$dbh = @oci_connect($username, $password, $tns);
        if (!self::$dbh) {
            throw new Exception("Connection error", -1);
        } else {
            self::$instance = $this;
        }
    }

//:-

    public function __call($func, $args) {
        $d = self::$dbh;

        if (!@call_user_func_array(array($d, $func), $args)) {
            $err = error_get_last();
            throw new Exception('ERROR CALLING: ' . $func . ' ' . $err['message'], $err['type']);
        }
    }

    public function getAttribute($attribute) {

        try {

            if ($attribute == PDO::ATTR_DRIVER_NAME) {
                return self::$DRIVER_NAME;
            } else {
                return null;
            }
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public function commit() {
        try {
            return oci_commit(self::$dbh);
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public function setAttribute($attribute, $value) {
        return self::$dbh->setAttribute($attribute, $value);
    }

//

    public function prepare($sql) {
        try {
            $stmt = oci_parse(self::$dbh, $sql);

            $ret = new Rebel_DB_PDO_PDOStatement(&self::$dbh, &$stmt);
            $ret->setQueryString($sql);
            $ret->stmt = $stmt;
            return $ret;
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    const OCI_OBJECT = 33;

    public function query($query, $fetch=OCI_ASSOC) {
        try {
            $oci_stmt = oci_parse(self::$dbh, $query);
            if ($stmt = @oci_execute($oci_stmt)) {
                $rs = array();
                switch ($fetch) {
                    default:
                    case OCI_ASSOC:
                        while ($row = oci_fetch_array($oci_stmt, OCI_ASSOC)) {
                            array_push($rs, $row);
                        }
                        break;
                    case self::OCI_OBJECT:
                        while ($row = oci_fetch_object($oci_stmt)) {
                            array_push($rs, $row);
                        }
                        break;
                }
                oci_free_cursor($oci_stmt);
                return $rs;
            } else {
                $err = oci_error(self::$dbh);
                throw new Exception($err['message'] . $err['sqltext'], $err['code']);
            }
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public function exec($query) {
        try {
            throw new Exception('PDO::exec FOR ORACLE NOT YET IMPLEMENTED IN REBEL');
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public function quote($string, $parameter_type=null) {
        try {
            return "'" . addslashes($string) . "'";
//				return self::$dbh->quote($string,$parameter_type);
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public static function validateQuery(PDOStatement &$stmt) {
        if (!$stmt->execute()) {
            $err = $stmt->errorInfo();
            throw new Exception($err[2], $err[1]);
        }
    }

//:-

    public function beginTransaction() {
        try {
            return true;
        } catch (Exception $e) {
            throw $e;
        }
    }

//

    public function rollBack() {
        try {
            return oci_rollback(self::$dbh);
        } catch (Exception $e) {
            throw $e;
        }
    }

//
}

///
